/*******************************************************************************
* Copyright (c) 2010, 2018 西安秦晔信息科技有限公司
* Licensed under the Apache License, Version 2.0 (the "License");
*    you may not use this file except in compliance with the License.
*    You may obtain a copy of the License at
*
*       http://www.apache.org/licenses/LICENSE-2.0
*
*    Unless required by applicable law or agreed to in writing, software
*    distributed under the License is distributed on an "AS IS" BASIS,
*    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*    See the License for the specific language governing permissions and
*    limitations under the License.
*******************************************************************************/
package com.qinyeit.serviceapp.service.organization.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.qinyeit.serviceapp.entity.Branch;
import com.qinyeit.serviceapp.entity.Department;
import com.qinyeit.serviceapp.entity.District;
import com.qinyeit.serviceapp.entity.system.ManagementPermission;
import com.qinyeit.serviceapp.entity.system.ManagementRole;
import com.qinyeit.serviceapp.exception.BusinessRunTimeException;
import com.qinyeit.serviceapp.repository.organization.DistrictRepository;
import com.qinyeit.serviceapp.service.organization.BranchService;
import com.qinyeit.serviceapp.service.organization.DepartmentService;
import com.qinyeit.serviceapp.service.organization.DistrictService;
import com.qinyeit.serviceapp.utils.SearchUtils;
import com.qinyetech.springstage.core.entity.search.SearchFilterHelper;
import com.qinyetech.springstage.core.entity.search.SearchOperator;
import com.qinyetech.springstage.core.entity.search.Searchable;
import com.qinyetech.springstage.core.lang.QyMap;
import com.qinyetech.springstage.core.repository.jdbc.PageNamedParameterJdbcTemplate;
import com.qinyetech.springstage.core.service.BaseTreeableService;
import com.qinyetech.springstage.core.utils.JSONUtils;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

/** 
 * ClassName: DistrictServiceImpl <br/> 
 * Function: 区域 业务实现 <br/> 
 * date: 2018-11-20 13:20:11 <br/> 
 * 
 * @author liuwenjin
 * @version 1.0
 * @since JDK 1.8
 */
@Service
@Transactional
public class DistrictServiceImpl extends BaseTreeableService<District, Long> implements DistrictService {


	@Autowired
	private DistrictRepository districtRepository;
	@Autowired
	private DepartmentService departmentService;
	@Autowired
    private PageNamedParameterJdbcTemplate jdbcTemplate;
	@Autowired
    private BranchService branchService;

	@Override
    public District buildRoot() {
        District district = new District();
        district.setId(0L);
        district.setParentId(0L);
        district.setParentIds("");
        return district;
    }

    @Override
    public void saveData(JSONObject data, Long merchantGroupId) {
       Searchable searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
       searchable.addSearchParam("parentId_eq",0);
       District genDistrict = this.findOne(searchable);

       if(genDistrict==null){
           throw new BusinessRunTimeException("没有根节点",10002);
       }
       Long id = data.getLong("id");
       String name = data.getString("name");
       if(StringUtils.isBlank(name)){
           throw new BusinessRunTimeException("区域名称不能为空",10001);
       }
       District district = null;
       if(id!=null){
           district = this.findById(id);
           district.setName(name);
           district =  this.update(district);
       }else {
           district = new District();
           district.setName(name);
           district.setParentId(genDistrict.getId());
           district.setParentIds(genDistrict.getParentIds()+""+genDistrict.getId()+"/");
           district.setMerchantGroupId(merchantGroupId);
           district.setWeight(genDistrict.getWeight()+1);
           district = this.save(district);
       }
    }

    @Override
    public List<District> getBuildTree(Long merchantGroupId) {
        Searchable searchable=Searchable.newSearchable();
        searchable.addSort(new Sort(Sort.Direction.ASC, "weight"));
        searchable.addSearchParam("deleted_eq",false);
        searchable.addSearchParam("merchantGroupId_eq", merchantGroupId);
        List<District> models = findWithSort(searchable);//查询所有
        return associateList(models, 0l,false);
    }

    @Override
    public List<District> getBuildTree(Long merchantGroupId, Boolean useBranch) {
        Searchable searchable=Searchable.newSearchable();
        searchable.addSort(new Sort(Sort.Direction.ASC, "weight"));
        searchable.addSearchParam("deleted_eq",false);
        searchable.addSearchParam("merchantGroupId_eq", merchantGroupId);
        List<District> models = findWithSort(searchable);//查询所有
        return associateList(models, 0l,useBranch);
    }
    @Override
    public List<District> getBuildTree(Long merchantGroupId, Boolean useBranch,Boolean useDistrict) {
        Searchable searchable=Searchable.newSearchable();
        searchable.addSort(new Sort(Sort.Direction.ASC, "weight"));
        searchable.addSearchParam("deleted_eq",false);
        searchable.addSearchParam("merchantGroupId_eq", merchantGroupId);
        List<District> models = findWithSort(searchable);//查询所有
        return associateList3(models, 0l,useBranch,useDistrict);
    }

    @Override
    public List<District> getBuildTree(Long merchantGroupId, Boolean useBranch, List<Long> branchIds,Boolean flag) {
        Searchable searchable=Searchable.newSearchable();
        searchable.addSort(new Sort(Sort.Direction.ASC, "weight"));
        searchable.addSearchParam("deleted_eq",false);
        searchable.addSearchParam("merchantGroupId_eq", merchantGroupId);
        List<District> models = findWithSort(searchable);//查询所有
        return associateList2(models, 0l,useBranch,branchIds,flag);
    }

    @Override
    public QyMap getDepartment(Long id, Long merchantGroupId) {

	    if(id==null){
	        throw new BusinessRunTimeException("请选择区域",10001);
        }
        District district = this.findById(id);
	    if(district==null){
	        throw new BusinessRunTimeException("区域不存在",1002);
        }

        QyMap map = QyMap.NEW();
        Searchable searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
	    searchable.addSearchFilter(SearchFilterHelper.or(
	            SearchFilterHelper.newCondition("district.id", SearchOperator.eq,id),
                SearchFilterHelper.newCondition("district.parentIds",SearchOperator.like,"/"+id+"/")
        ));
        List<Department> departmentList = departmentService.findWithSort(searchable);

        map.setv("departmentList", JSONUtils.include(departmentList,"id","name","district.name:districtName","district.id:districtId","district.parentId:districtParentId",
                "district.parentIds:districtParentIds","operator","operatorName","state","createAt"));

        //区域是根节点 可管理显示区域子节点
        if(district.getParentId().intValue()==0){
            searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
            searchable.addSearchParam("parentId_ne",0);
            List<District> districtList = this.findWithSort(searchable);
            map.setv("districtList",JSONUtils.include(districtList,"id","name","createAt","parentId","parentIds"));
            map.setv("type","district");
        }else {
            //可管理显示店
            searchable = SearchUtils.newSearchableWithMerchantFilter(merchantGroupId);
            searchable.addSearchParam("districtId_eq",id);
            List<Branch> branchList = branchService.findWithSort(searchable);
            map.setv("branchList",JSONUtils.include(branchList,"id","name","state"));
            map.setv("type","branch");

        }
/*
        String sql = "SELECT r.* from management_roles r\n" +
                "LEFT JOIN districts d on d.id = r.attach_district_id \n" +
                "\n" +
                "where r.is_deleted = 0 and r.code != 'administrator' AND r.merchant_group_id = :merchantGroupId\n" +
                "and (d.id=:districtId or d.parent_ids like :districtParentId)";
        Map<String,Object> params = Maps.newHashMap();
        params.put("merchantGroupId",merchantGroupId);
        params.put("districtId",id);
        params.put("districtParentId","%/"+id+"/%");
        List<Map<String,Object>> mapList = jdbcTemplate.queryForList(sql,params);
        map.setv("roles",mapList);*/
        return map;
    }




    /**
     *
     * associateList:处理关联 <br>
     *
     * @author wuqing
     * @param models
     * 返回根节点集合
     * @since JDK 1.7
     */
    private List<District> associateList(List<District> models, Long id,Boolean useBranch){
        List<District> result= Lists.newArrayList();
        List<Branch> branchList =null;
        if(models!=null && models.size()>0){
            for (int i=0;i<models.size();i++) {
                District model = models.get(i);
                if(id.equals(model.getParentId())){
                    model.setChildren(associateList(models, (Long) model.getId(),useBranch));
                    model.setiBranch(false);
                    if(useBranch!=null && useBranch){
                        if(CollectionUtils.isEmpty(model.getChildren())){
                            branchList = branchService.getBranchByDistrictId(model.getId(),null,false);
                            branchList.forEach(x->{x.setiBranch(true);});
                            model.setChildren((JSONArray)JSONUtils.include(branchList,"id","name","districtId","state","iBranch","merchantId"));
                        }
                    }
                    result.add(model);
                }
            }
        }
        return result;
    }

    /**
     *
     * associateList:处理关联 <br>
     *
     * @author wuqing
     * @param models
     * 返回根节点集合
     * @since JDK 1.7
     */
    private List<District> associateList2(List<District> models, Long id,Boolean useBranch,List<Long> branchIds,Boolean flag){
        List<District> result= Lists.newArrayList();
        List<Branch> branchList =null;
        Searchable searchable = null;
        if(models!=null && models.size()>0){
            for (int i=0;i<models.size();i++) {
                District model = models.get(i);
                if(id.equals(model.getParentId())){
                    model.setChildren(associateList2(models, (Long) model.getId(),useBranch,branchIds,flag));
                    model.setiBranch(false);
                    if(useBranch!=null && useBranch){
                        if(CollectionUtils.isEmpty(model.getChildren())){
                            branchList = branchService.getBranchByDistrictId(model.getId(),branchIds,flag);
                            branchList.forEach(x->{x.setiBranch(true);});
                            model.setChildren((JSONArray)JSONUtils.include(branchList,"id","name","districtId","state","iBranch","merchantId"));
                        }
                    }
                    result.add(model);
                }
            }
        }
        return result;
    }

    /**
     *
     * associateList:处理关联 <br>
     *
     * @author wuqing
     * @param models
     * 返回根节点集合
     * @since JDK 1.7
     */
    private List<District> associateList3(List<District> models, Long id,Boolean useBranch,Boolean useDistrict){
        List<District> result= Lists.newArrayList();
        List<Branch> branchList =null;
        if(models!=null && models.size()>0){
            for (int i=0;i<models.size();i++) {
                District model = models.get(i);
                if(id.equals(model.getParentId())){
                    if(useDistrict){
                        model.setChildren(associateList3(models, (Long) model.getId(),useBranch,useDistrict));
                        model.setiBranch(false);
                        if(useBranch!=null && useBranch){
                            if(CollectionUtils.isEmpty(model.getChildren())){
                                branchList = branchService.getBranchByDistrictId(model.getId(),null,false);
                                branchList.forEach(x->{x.setiBranch(true);});
                                model.setChildren((JSONArray)JSONUtils.include(branchList,"id","name","districtId","state","iBranch","merchantId"));
                            }
                        }
                        result.add(model);
                    }else {
                        branchList = branchService.getBranchByDistrictId(model.getId(),null,false);
                        branchList.forEach(x->{x.setiBranch(true);});
                        model.setChildren((JSONArray)JSONUtils.include(branchList,"id","name","districtId","state","iBranch","merchantId"));
                    }

                }
            }
        }
        return result;
    }



}